#include "../head/server.h"

// 产生盐值
void generate_salt(char *salt, int length)
{
	const char charset[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
	srand(time(NULL));
	salt[0] = '$';
	salt[1] = '6';
	salt[2] = '$';
	salt[19] = '$';
	for (int i = 3; i < length; ++i)
	{
		salt[i] = charset[rand() % (sizeof(charset) - 1)];
	}
}

// 动态加载配置文件config.ini中的的内容
int getparameter(char *key, char *value)
{
	FILE *file = fopen("config.ini", "r");
	while (1)
	{
		char line[100];
		bzero(line, sizeof(line));
		// 读一行数据
		char *res = fgets(line, sizeof(line), file);
		if (res == NULL)
		{
			char buf[] = "没有要找的内容 \n";
			memcpy(value, buf, strlen(buf));
			return -1;
		}
		// 处理数据
		char *line_key = strtok(line, "=");
		if (strcmp(key, line_key) == 0)
		{
			// 要找的内容
			char *line_value = strtok(NULL, "=");
			memcpy(value, line_value, strlen(line_value) - 1);
			return 0;
		}
	}

	return 0;
}

// jwt加密
void jwt_encode(char *token, char *username)
{
	// 用于存储生成的JWT字符串
	char *jwt;
	// JWT字符串的长度
	size_t jwt_length;
	// 初始化编码参数结构体
	struct l8w8jwt_encoding_params params;
	l8w8jwt_encoding_params_init(&params);
	// 设置JWT使用的算法，这里使用HS512
	params.alg = L8W8JWT_ALG_HS512;
	// 设置JWT的主要荷载部分内容:
	// 主题
	params.sub = "netdisk";
	// 签发者
	params.iss = "zz";
	// 接收方
	params.aud = username;
	// token过期/有效时间(0x7fffffff:最大值-> 2038年1月19日)
	params.exp = 0x7fffffff;
	// token签发时间
	params.iat = 0;
	// 设置加密密钥
	params.secret_key = (unsigned char *)"zz string token key";
	params.secret_key_length = strlen((char *)params.secret_key);
	// 输出变量
	params.out = &jwt;
	params.out_length = &jwt_length;
	// 加密
	l8w8jwt_encode(&params);

	memcpy(token, jwt, strlen(jwt));
	
	// 释放token 字符串的内存
	l8w8jwt_free(jwt);
}
// jwt解密

// 得到绝对路径
void getAbsolutePath(char *path)
{
	char *token;
	char *rest = path;
	char result[100]; // 使用临时缓冲区存储结果路径
	result[0] = '\0'; // 初始化结果路径为空

	while ((token = strtok_r(rest, "/", &rest)))
	{
		if (strcmp(token, "..") == 0)
		{
			// 如果当前token是"..", 则回退到上一级目录
			char *prevToken = strrchr(result, '/');
			if (prevToken)
			{
				*prevToken = '\0'; // 截断到上一级目录
			}
		}
		else if (strcmp(token, ".") != 0)
		{
			// 如果当前token不是"."，则将其添加到结果路径中
			strcat(result, "/");
			strcat(result, token);
		}
	}

	if (!strcmp(result, "\0"))
	{
		strcat(result, "/");
	}
	// 将最终结果复制回原始路径
	strcpy(path, result);
}

// 通过绝对路径，查询path是否在表中
int is_path(MYSQL *mysql, char *path)
{
	char sql[1024] = {0};
	sprintf(sql, "select count(*) from all_user_file where file_path = '%s';", path);
	puts(sql);
	int qret = mysql_query(mysql, sql);
	if (qret != 0)
	{
		fprintf(stderr, "mysql_query:%s\n", mysql_error(mysql));
		return 0;
	}
	MYSQL_RES *res = mysql_store_result(mysql);
	if (res == NULL)
	{
		fprintf(stderr, "mysql_query:%s\n", mysql_error(mysql));
		mysql_free_result(res);
		return 0;
	}
	MYSQL_ROW row = mysql_fetch_row(res);
	if (row == NULL)
	{
		fprintf(stderr, "mysql_query:%s\n", mysql_error(mysql));
		mysql_free_result(res);
		return 0;
	}
	// int res = atoi(row[0]);
	mysql_free_result(res);

	return atoi(row[0]);
}

// 传入任意路径/文件，查询是否存在于file_table中
int check_file_existance(MYSQL *mysql, char *path, char *user_name)
{
	// puts(path);

	// 从数据库中拿到当前路径
	char *cur_path = get_current_path_by_username(mysql, user_name);

	// 获取绝对路径
	char absolutePath[1024] = {0};
	if (!memcmp(path, "/", strlen("/")))
	{
		memcpy(absolutePath, path, strlen(path));
	}
	else
	{
		memcpy(absolutePath, cur_path, strlen(cur_path));
		strcat(absolutePath, "/");
		strcat(absolutePath, path);
	}
	getAbsolutePath(absolutePath);

	int ret = is_path(mysql, absolutePath);
	if (ret)
	{
		return 0; // 该路径在表中
	}
	return 1; // 该路径不在表中
}